test_sources = [
  'a1-bug.c',
  'a1-clip.c',
  'a1-fill.c',
  'a1-image-sample.c',
  'a1-mask.c',
  'a1-mask-sample.c',
  'a1-sample.c',
  'a1-traps-sample.c',
  'a1-rasterisation.c',
  'a8-clear.c',
  'a8-mask.c',
  'aliasing.c',
  'alpha-similar.c',
  'arc-direction.c',
  'arc-infinite-loop.c',
  'arc-looping-dash.c',
  'api-special-cases.c',
  'big-line.c',
  'big-empty-box.c',
  'big-empty-triangle.c',
  'big-little-box.c',
  'big-little-triangle.c',
  'bug-spline.c',
  'big-trap.c',
  'bilevel-image.c',
  'bug-277.c',
  'bug-361.c',
  'bug-40410.c',
  'bug-431.c',
  'bug-448.c',
  'bug-535.c',
  'bug-51910.c',
  'bug-75705.c',
  'bug-84115.c',
  'bug-bo-rectangular.c',
  'bug-bo-collins.c',
  'bug-bo-ricotz.c',
  'bug-source-cu.c',
  'bug-extents.c',
  'bug-image-compositor.c',  
  'bug-seams.c',
  'caps.c',
  'checkerboard.c',
  'caps-joins.c',
  'caps-joins-alpha.c',
  'caps-joins-curve.c',
  'caps-tails-curve.c',
  'caps-sub-paths.c',
  'clear.c',
  'clear-source.c',
  'clip-all.c',
  'clip-complex-bug61592.c',
  'clip-complex-shape.c',
  'clip-contexts.c',
  'clip-disjoint.c',
  'clip-disjoint-hatching.c',
  'clip-disjoint-quad.c',
  'clip-device-offset.c',
  'clip-double-free.c',
  'clip-draw-unbounded.c',
  'clip-empty.c',
  'clip-empty-group.c',
  'clip-empty-save.c',
  'clip-fill.c',
  'clip-fill-no-op.c',
  'clip-fill-rule.c',
  'clip-fill-rule-pixel-aligned.c',
  'clip-group-shapes.c',
  'clip-image.c',
  'clip-intersect.c',
  'clip-mixed-antialias.c',
  'clip-nesting.c',
  'clip-operator.c',
  'clip-push-group.c',
  'clip-polygons.c',
  'clip-rectilinear.c',
  'clip-shape.c',
  'clip-stroke.c',
  'clip-stroke-no-op.c',
  'clip-text.c',
  'clip-twice.c',
  'clip-twice-rectangle.c',
  'clip-unbounded.c',
  'clip-zero.c',
  'clipped-group.c',
  'clipped-surface.c',
  'close-path.c',
  'close-path-current-point.c',
  'composite-integer-translate-source.c',
  'composite-integer-translate-over.c',
  'composite-integer-translate-over-repeat.c',
  'copy-disjoint.c',
  'copy-path.c',
  'coverage.c',
  'create-for-stream.c',
  'create-from-broken-png-stream.c',
  'create-from-png.c',
  'create-from-png-16bit.c',
  'create-from-png-stream.c',
  'culled-glyphs.c',
  'curve-to-as-line-to.c',
  'dash-caps-joins.c',
  'dash-curve.c',
  'dash-infinite-loop.c',
  'dash-no-dash.c',
  'dash-offset.c',
  'dash-offset-negative.c',
  'dash-scale.c',
  'dash-state.c',
  'dash-zero-length.c',
  'degenerate-arc.c',
  'degenerate-arcs.c',
  'degenerate-curve-to.c',
  'degenerate-dash.c',
  'degenerate-linear-gradient.c',
  'degenerate-path.c',
  'degenerate-pen.c',
  'degenerate-radial-gradient.c',
  'degenerate-rel-curve-to.c',
  'degenerate-solid-dash.c',
  'drunkard-tails.c',
  'device-offset.c',
  'device-offset-fractional.c',
  'device-offset-positive.c',
  'device-offset-scale.c',
  'dithergradient.c',
  'error-setters.c',
  'extend-pad.c',
  'extend-pad-border.c',
  'extend-pad-similar.c',
  'extend-reflect.c',
  'extend-reflect-similar.c',
  'extend-repeat.c',
  'extend-repeat-similar.c',
  'extended-blend.c',
  'fallback.c',
  'fill-alpha.c',
  'fill-alpha-pattern.c',
  'fill-and-stroke.c',
  'fill-and-stroke-alpha.c',
  'fill-and-stroke-alpha-add.c',
  'fill-degenerate-sort-order.c',
  'fill-disjoint.c',
  'fill-empty.c',
  'fill-image.c',
  'fill-missed-stop.c',
  'fill-rule.c',
  'filter-bilinear-extents.c',
  'filter-nearest-offset.c',
  'filter-nearest-transformed.c',
  'finer-grained-fallbacks.c',
  'font-face-get-type.c',
  'font-matrix-translation.c',
  'font-options.c',
  'glyph-cache-pressure.c',
  'glyph-path.c',
  'get-and-set.c',
  'get-clip.c',
  'get-group-target.c',
  'get-path-extents.c',
  'gradient-alpha.c',
  'gradient-constant-alpha.c',
  'gradient-scale-crash.c',
  'gradient-zero-stops.c',
  'gradient-zero-stops-mask.c',
  'group-clip.c',
  'group-paint.c',
  'group-state.c',
  'group-unaligned.c',
  'hairline.c',
  'half-coverage.c',
  'halo.c',
  'hatchings.c',
  'horizontal-clip.c',
  'huge-linear.c',
  'huge-radial.c',
  'image-surface-source.c',
  'image-bug-710072.c',
  'implicit-close.c',
  'infinite-join.c',
  'in-fill-empty-trapezoid.c',
  'in-fill-trapezoid.c',
  'invalid-matrix.c',
  'inverse-text.c',
  'inverted-clip.c',
  'joins.c',
  'joins-loop.c',
  'joins-star.c',
  'joins-retrace.c',
  'large-clip.c',
  'large-font.c',
  'large-source.c',
  'large-source-roi.c',
  'large-twin-antialias-mixed.c',
  'leaks.c',
  'leaky-dash.c',
  'leaky-dashed-rectangle.c',
  'leaky-dashed-stroke.c',
  'leaky-polygon.c',
  'line-width.c',
  'line-width-large-overlap.c',
  'line-width-overlap.c',
  'line-width-scale.c',
  'line-width-tolerance.c',
  'line-width-zero.c',
  'linear-gradient.c',
  'linear-gradient-extend.c',
  'linear-gradient-large.c',
  'linear-gradient-one-stop.c',
  'linear-gradient-reflect.c',
  'linear-gradient-subset.c',
  'linear-step-function.c',
  'linear-uniform.c',
  'long-dashed-lines.c',
  'long-lines.c',
  'map-to-image.c',
  'mask.c',
  'mask-alpha.c',
  'mask-ctm.c',
  'mask-glyphs.c',
  'mask-surface-ctm.c',
  'mask-transformed-image.c',
  'mask-transformed-similar.c',
  'mesh-pattern.c',
  'mesh-pattern-accuracy.c',
  'mesh-pattern-conical.c',
  'mesh-pattern-control-points.c',
  'mesh-pattern-fold.c',
  'mesh-pattern-overlap.c',
  'mesh-pattern-transformed.c',
  'mime-data.c',
  'mime-surface-api.c',
  'miter-precision.c',
  'move-to-show-surface.c',
  'negative-stride-image.c',
  'new-sub-path.c',
  'nil-surface.c',
  'operator.c',
  'operator-alpha.c',
  'operator-alpha-alpha.c',
  'operator-clear.c',
  'operator-source.c',
  'operator-www.c',
  'outline-tolerance.c',
  'overflow.c',
  'over-above-source.c',
  'over-around-source.c',
  'over-below-source.c',
  'over-between-source.c',
  'overlapping-boxes.c',
  'overlapping-glyphs.c',
  'overlapping-dash-caps.c',
  'paint.c',
  'paint-clip-fill.c',
  'paint-repeat.c',
  'paint-source-alpha.c',
  'paint-with-alpha.c',
  'paint-with-alpha-group-clip.c',
  'partial-clip-text.c',
  'partial-coverage.c',
  'pass-through.c',
  'path-append.c',
  'path-currentpoint.c',
  'path-stroke-twice.c',
  'path-precision.c',
  'pattern-get-type.c',
  'pattern-getters.c',
  'pdf-isolated-group.c',
  'pixman-downscale.c',
  'pixman-rotate.c',
  'png.c',
  'push-group.c',
  'push-group-color.c',
  'push-group-path-offset.c',
  'radial-gradient.c',
  'radial-gradient-extend.c',
  'radial-outer-focus.c',
  'random-clips.c',
  'random-intersections-eo.c',
  'random-intersections-nonzero.c',
  'random-intersections-curves-eo.c',
  'random-intersections-curves-nz.c',
  'raster-source.c',
  'record.c',
  'record1414x.c',
  'record2x.c',
  'record90.c',
  'recordflip.c',
  'record-extend.c',
  'record-neg-extents.c',
  'record-mesh.c',
  'record-replay-extend.c',
  'record-transform-paint.c',
  'record-write-png.c',
  'recording-ink-extents.c',
  'recording-surface-pattern.c',
  'recording-surface-extend.c',
  'rectangle-rounding-error.c',
  'rectilinear-fill.c',
  'rectilinear-grid.c',
  'rectilinear-miter-limit.c',
  'rectilinear-dash.c',
  'rectilinear-dash-scale.c',
  'rectilinear-stroke.c',
  'reflected-stroke.c',
  'rel-path.c',
  'rgb24-ignore-alpha.c',
  'rotate-image-surface-paint.c',
  'rotate-stroke-box.c',
  'rotated-clip.c',
  'rounded-rectangle-fill.c',
  'rounded-rectangle-stroke.c',
  'round-join-bug-520.c',
  'sample.c',
  'scale-down-source-surface-paint.c',
  'scale-offset-image.c',
  'scale-offset-similar.c',
  'scale-source-surface-paint.c',
  'scaled-font-zero-matrix.c',
  'stroke-ctm-caps.c',
  'stroke-clipped.c',
  'stroke-image.c',
  'stroke-open-box.c',
  'select-font-face.c',
  'select-font-no-show-text.c',
  'self-copy.c',
  'self-copy-overlap.c',
  'self-intersecting.c',
  'set-source.c',
  'show-glyphs-advance.c',
  'show-glyphs-many.c',
  'show-text-current-point.c',
  'shape-general-convex.c',
  'shape-sierpinski.c',
  'shifted-operator.c',
  'simple.c',
  'skew-extreme.c',
  'smask.c',
  'smask-fill.c',
  'smask-image-mask.c',
  'smask-mask.c',
  'smask-paint.c',
  'smask-stroke.c',
  'smask-text.c',
  'smp-glyph.c',
  'solid-pattern-cache-stress.c',
  'source-clip.c',
  'source-clip-scale.c',
  'source-surface-scale-paint.c',
  'spline-decomposition.c',
  'stride-12-image.c',
  'stroke-pattern.c',
  'subsurface.c',
  'subsurface-image-repeat.c',
  'subsurface-repeat.c',
  'subsurface-reflect.c',
  'subsurface-pad.c',
  'subsurface-modify-child.c',
  'subsurface-modify-parent.c',
  'subsurface-outside-target.c',
  'subsurface-scale.c',
  'subsurface-similar-repeat.c',
  'surface-finish-twice.c',
  'surface-pattern.c',
  'surface-pattern-big-scale-down.c',
  'surface-pattern-operator.c',
  'surface-pattern-scale-down.c',
  'surface-pattern-scale-down-extend.c',
  'surface-pattern-scale-up.c',
  'text-antialias.c',
  'text-antialias-subpixel.c',
  'text-cache-crash.c',
  'text-glyph-range.c',
  'text-pattern.c',
  'text-rotate.c',
  'text-subpixel.c',
  'text-transform.c',
  'text-unhinted-metrics.c',
  'text-zero-len.c',
  'thin-lines.c',
  'tighten-bounds.c',
  'tiger.c',
  'toy-font-face.c',
  'transforms.c',
  'translate-show-surface.c',
  'trap-clip.c',
  'twin.c',
  'twin-antialias-gray.c',
  'twin-antialias-mixed.c',
  'twin-antialias-none.c',
  'twin-antialias-subpixel.c',
  'unaligned-box.c',
  'unantialiased-shapes.c',
  'unbounded-operator.c',
  'unclosed-strokes.c',
  'user-data.c',
  'user-font.c',
  'user-font-color.c',
  'user-font-mask.c',
  'user-font-proxy.c',
  'user-font-rescale.c',
  'user-font-subpixel.c',
  'world-map.c',
  'white-in-noop.c',
  'xcb-huge-image-shm.c',
  'xcb-huge-subimage.c',
  'xcb-stress-cache.c',
  'xcb-snapshot-assert.c',
  'xcomposite-projection.c',
  'xlib-expose-event.c',
  'zero-alpha.c',
  'zero-mask.c',
]

test_pthread_sources = [
  'pthread-same-source.c',
  'pthread-show-text.c',
  'pthread-similar.c',
]

# Only font-variations.c is ft-specific according to Makefile.sources, the other
# depend on fontconfig
test_ft_font_sources = [
  'font-variations.c',
  'bitmap-font.c',
  'ft-color-font.c',
  'ft-font-create-for-ft-face.c',
  'ft-show-glyphs-positioning.c',
  'ft-show-glyphs-table.c',
  'ft-text-vertical-layout-type1.c',
  'ft-text-vertical-layout-type3.c',
  'ft-text-antialias-none.c',
  'ft-variable-font.c',
]

test_ft_svg_font_sources = [
  'ft-svg-color-font.c',
]

test_ft_svg_ttx_font_sources = [
  'ft-svg-cairo-logo.c',
  'ft-svg-render.c',
  'ft-svg-render-color.c'
]

test_quartz_sources = [
  'quartz-surface-source.c',
  'quartz-color-font.c',
]

test_pdf_sources = [
  'pdf-features.c',
  'pdf-mime-data.c',
  'pdf-operators-text.c',
  'pdf-surface-source.c',
  'pdf-tagged-text.c',
]

test_pdf_structure_sources = [
  'pdf-structure.c',
]

test_ps_sources = [
  'ps-eps.c',
  'ps-features.c',
  'ps-surface-source.c',
]

test_svg_sources = [
  'svg-surface.c',
  'svg-clip.c',
  'svg-surface-source.c',
]

test_xcb_sources = [
  'xcb-surface-source.c',
]

test_xlib_sources = [
  'xlib-surface.c',
  'xlib-surface-source.c',
]

test_xlib_xrender_sources = [
  'get-xrender-format.c',
]

test_multi_page_sources = [
  'multi-page.c',
  'mime-unique-id.c',
]

test_fallback_resolution_sources = [
  'create-regions.c',
  'fallback-resolution.c',
]

cairo_test_suite_sources = [
  'buffer-diff.c',
  'cairo-test.c',
  'cairo-test-runner.c',
]

cairo_test_trace_sources = [
  'cairo-test-trace.c',
  'buffer-diff.c',
]

imagediff_sources = [
  'imagediff.c',
  'buffer-diff.c',
]

png_flatten_sources = [
  'png-flatten.c',
]

pdf2png_sources = [
  'pdf2png.c',
]

svg2png_sources = [
  'svg2png.c',
]

ps2png_sources = [
  'ps2png.c',
]

test_ttx_fonts = [
  'cairo-logo-font.ttx',
  'cairo-svg-test-color.ttx',
  'cairo-svg-test-doc.ttx',
  'cairo-svg-test-fill.ttx',
  'cairo-svg-test-gradient.ttx',
  'cairo-svg-test-path.ttx',
  'cairo-svg-test-shapes.ttx',
  'cairo-svg-test-stroke.ttx',
  'cairo-svg-test-transform.ttx',
]

build_any2ppm = false
has_multipage_surfaces = false
add_fallback_resolution = false

if conf.get('CAIRO_HAS_REAL_PTHREAD', 0) == 1
  test_sources += test_pthread_sources
endif

if feature_conf.get('CAIRO_HAS_FT_FONT', 0) == 1 and feature_conf.get('CAIRO_HAS_FC_FONT', 0) == 1
  test_sources += test_ft_font_sources
  if conf.get('HAVE_FT_SVG_DOCUMENT', 0) == 1
    test_sources += test_ft_svg_font_sources
    if conf.get('CAIRO_CAN_TEST_TTX_FONT', 0) == 1
      test_sources += test_ft_svg_ttx_font_sources
    endif
  endif
endif

if feature_conf.get('CAIRO_HAS_QUARTZ_SURFACE', 0) == 1
  test_sources += test_quartz_sources
endif

if feature_conf.get('CAIRO_HAS_PDF_SURFACE', 0) == 1
  test_sources += test_pdf_sources
  if host_machine.system() != 'windows'
    test_sources += test_pdf_structure_sources
  endif
  has_multipage_surfaces = true
  add_fallback_resolution = true
  build_any2ppm = true
endif

if feature_conf.get('CAIRO_HAS_PS_SURFACE', 0) == 1
  test_sources += test_ps_sources
  has_multipage_surfaces = true
  add_fallback_resolution = true
  build_any2ppm = true
endif

if feature_conf.get('CAIRO_HAS_SVG_SURFACE', 0) == 1
  test_sources += test_svg_sources
  build_any2ppm = true
  add_fallback_resolution = true
endif

if feature_conf.get('CAIRO_HAS_XCB_SURFACE', 0) == 1
  test_sources += test_xcb_sources
endif

if feature_conf.get('CAIRO_HAS_XLIB_SURFACE', 0) == 1
  test_sources += test_xlib_sources
endif

if feature_conf.get('CAIRO_HAS_XLIB_XRENDER_SURFACE', 0) == 1
  test_sources += test_xlib_xrender_sources
endif

if has_multipage_surfaces
  test_sources += test_multi_page_sources
endif

if add_fallback_resolution
  test_sources += test_fallback_resolution_sources
endif

if feature_conf.get('CAIRO_HAS_SCRIPT_SURFACE', 0) == 1
  build_any2ppm = true
endif

cairo_test_constructors = custom_target('cairo-test-constructors.c',
  input: files(test_sources),
  output: 'cairo-test-constructors.c',
  command: [python3, files('make-cairo-test-constructors.py')[0], '@OUTPUT@', '@INPUT@'])

test_depends = []

subdir('pdiff')

if conf.get('CAIRO_CAN_TEST_PDF_SURFACE', 0) == 1
  exe = executable('pdf2png', pdf2png_sources,
    dependencies: deps + test_deps,
  )
endif

if conf.get('CAIRO_CAN_TEST_SVG_SURFACE', 0) == 1
  exe = executable('svg2png', svg2png_sources,
    dependencies: deps + test_deps,
  )
endif

if conf.get('CAIRO_HAS_SPECTRE', 0) == 1
  exe = executable('ps2png', ps2png_sources,
    dependencies: deps + test_deps,
  )
endif

if build_any2ppm
  any2ppm_exe = executable('any2ppm', 'any2ppm.c',
    include_directories: [incbase],
    dependencies: deps + test_deps + [libcairo_dep, libcairoscript_dep],
  )
  test_depends += [any2ppm_exe]
endif

if have_shm and conf.get('CAIRO_HAS_INTERPRETER', 0) == 1
  cairo_test_trace_exe = executable('cairo-test-trace', cairo_test_trace_sources,
  include_directories: [incbase],
  c_args: pthread_c_args,
  link_args: extra_link_args,
  dependencies: deps + test_deps + [rt_dep, libcairo_dep, cairoboilerplate_dep, libpdiff_dep, libcairomissing_dep, libcairoscript_dep])
endif

exe = executable('cairo-test-suite', [cairo_test_suite_sources, test_sources, cairo_test_constructors],
  include_directories: [incbase],
  link_args: extra_link_args,
  dependencies: deps + test_deps + [libcairo_dep, cairoboilerplate_dep,
    libpdiff_dep],
)

fs = import('fs')
build_dir_files = ['completion.bash', 'index.html', 'testtable.js', 'view-test-results.py']
foreach file : build_dir_files
  fs.copyfile(file)
endforeach

if build_machine.system() != 'windows'
  run_command('ln', '-sfn',
              meson.current_source_dir(),
              meson.current_build_dir() / 'srcdir',
              check: true)
endif

if ttx.found()
  # By default, if the output file exists, ttx creates a new name. We specify the full
  # output name to make ttx overwrite the existing file instead of creating a new file.
  foreach ttx_font : test_ttx_fonts
    custom_target(ttx_font,
                  input: ttx_font,
                  command: [ ttx, '-q', '-o', '@OUTDIR@' / '@BASENAME@.ttf', '@INPUT@' ],
                  output: '@BASENAME@.ttf',
                  build_by_default: true)
  endforeach
endif

env = environment()

env.set('srcdir', meson.current_source_dir())

test('cairo', exe,
  timeout: 60 * 60,
  env: env,
  suite: ['cairo-test-suite', 'slow'],
  workdir: meson.current_build_dir(),
  depends: test_depends)

# The SVG renderer debug tools can only be built if the _cairo_debug_svg_render()
# function has been exposed by defining DEBUG_SVG_RENDER
if conf.get('HAVE_FT_SVG_DOCUMENT', 0) == 1 and cc.has_define('DEBUG_SVG_RENDER')
  subdir('svg')
endif
